package info.nixbear.tgcms.services.dao.appengine;

import info.nixbear.tgcms.domain.Attachment;
import info.nixbear.tgcms.domain.Page;
import info.nixbear.tgcms.domain.Website;
import info.nixbear.tgcms.services.dao.DaoException;
import info.nixbear.tgcms.services.dao.PMF;
import info.nixbear.tgcms.services.dao.PageDao;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

public class AppenginePageDao extends AppengineEntityDao<Page> implements PageDao {

	Logger logger = LoggerFactory.getLogger(AppenginePageDao.class);

	public AppenginePageDao() {
		super(Page.class);
	}
	
	@Override
	public Page get(Long id) throws DaoException {
		Website website = new AppengineWebsiteDao().getDefaultWebsite();
		Key key = KeyFactory.createKey(website.getKey(), Page.class.getSimpleName(), id);

		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.getFetchPlan().addGroup("all");
		pm.setDetachAllOnCommit(true);

		Page page = null;
		try {
			page = pm.getObjectById(Page.class, key);
			page = pm.detachCopy(page);
			if(page != null && page.getAttachments() != null) {
				page.setAttachments(new ArrayList<Attachment>(pm.detachCopyAll(page.getAttachments())));
			}
		} catch (Exception e) {
			logger.error(
					"Entity " + Page.class.getSimpleName() + " with id" + id + ", key " + key
							+ " not fount on the website " + website.getName() + ", id: "
							+ website.getId(), e);
		} finally {
			pm.close();
		}
		return page;
	}


	@Override
	public Page findByUrl(String url) {
		if (url == null) {
			return null;
		}

		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.getFetchPlan().addGroup("all");
		pm.setDetachAllOnCommit(true);

		Page page = null;
		
		try {

			Query query = pm.newQuery("select from " + Page.class.getName()
					+ " where url == urlParam " + " parameters String urlParam ");

			@SuppressWarnings("unchecked")
			List<Page> pages = (List<Page>) query.execute(url);

			page = (pages == null || pages.size() == 0) ? null : pages.get(0);

			page = pm.detachCopy(page);
			if(page != null && page.getAttachments() != null) {
				page.setAttachments(new ArrayList<Attachment>(pm.detachCopyAll(page.getAttachments())));
			}
		} finally {
			pm.close();
		}

		return page;
	}

	@Override
	public Page put(Page page) throws DaoException {
		Set<Long> oldAttachmentIds = new HashSet<Long>();
		if(page.getId() != null) {
			Page p = this.get(page.getId());
			if(p != null && p.getAttachments() != null) {
				for(Attachment a : p.getAttachments()) {
					oldAttachmentIds.add(a.getId());
				}
			}
		}
		if(page.getAttachments() != null && page.getUrl() != null) {
			for(Attachment attachment : page.getAttachments()) {
				if(attachment.getUrl() == null || attachment.getUrl().isEmpty()) {
					String baseUrl = page.getUrl();
					if(page.getUrl().endsWith(".html")) {
						baseUrl = page.getUrl().substring(0, page.getUrl().length() - 5);
					}
					String url = null;
					for(int i=0; i<1000; i++) {
						url = baseUrl+"/"+i+".html";
						boolean found = false;
						for(Attachment a : page.getAttachments()) {
							if(url.equals(a.getUrl())) {
								found = true;
								break;
							}
						}
						if(!found) {
							break;
						}
					}
					attachment.setUrl(url);
				}
				prepare(attachment);
			}
		}
		Page ret = super.put(page);
		
		AppengineAttachmentDao aad = new AppengineAttachmentDao();
		for(Long aId : oldAttachmentIds) {
			Attachment a = aad.get(aId);
			if(a != null) {
				aad.delete(a);
			}
		}
		
		return ret;
	}
}
